package yxm.zyf.love.arithmetic;
import java.util.HashMap;
import java.util.Map;
 /**
  * https://blog.csdn.net/xzknet/article/details/102504635
  * s在下面的数中间填上“+”，“-”，使计算结果为100。 使123456789=100
  * */
public class AoShuJiaJianQiuHe {
	static Map<String, Object> jieguoMap = new HashMap<>();
 
	/**
	 * 输出结果
	 * 
	 * @param oi
	 * @param sub_array
	 * @param xy
	 * @param jieguo
	 */
	public static void print(int[] oi, int[] sub_array, int[] xy, int jieguo) {
		StringBuffer sb = new StringBuffer();
		sb.append(sub_array[0]);
		for (int i = 1; i < sub_array.length; i++) {
			if (oi[i - 1] == 0) {
				sb.append("+" + sub_array[i]);
			} else {
				sb.append("-" + sub_array[i]);
			}
		}
		sb.append("=" + jieguo);
		if (false == jieguoMap.containsKey(sb.toString())) {
			jieguoMap.put(sb.toString(), new Object());
			System.out.println(sb);
		}
		return;
	}
 
	/**
	 * 计算结果
	 * 
	 * @param n
	 * @param oi
	 * @param sub_array
	 * @param xy
	 */
	public static void jiSuan_jieguo(int n, int[] oi, int[] sub_array, int[] xy) {
		int qiuhe = sub_array[0];
		for (int i = 1; i < sub_array.length; i++) {
			// 0为加，1为减 0-1变量
			if (oi[i - 1] == 0) {
				qiuhe = qiuhe + sub_array[i];
			} else {
				qiuhe = qiuhe - sub_array[i];
			}
		}
 
		if (qiuhe == 100) {
			print(oi, sub_array, xy, qiuhe); // 结果等于100输出
			return;
		}
		return;
	}
 
	/**
	 * 计算被符号分割的各各数 例如符号个数为3 符号位为3，5，7 则被符号分割的数为123，45，67，89
	 * 
	 * @param array
	 * @param n
	 * @param xy
	 * @param oi
	 */
	public static void jiSuan_even(int[] array, int n, int[] xy, int[] oi) {
		// array 要计算的数组 n为符号个数 xy保存的是符号的位置 oi保存的是加减符号
		int[] sub_array = new int[n + 1]; // 保存被符号分割的数 符号若为N个 则被符号分割的数的个数为N+1个
		for (int i = 0; i < n + 1; i++) {
			if (i == 0) {
				// 例如xy[i]=3 则sub_array[i]=1*100+2*10+3*1
				for (int j = 0; j < xy[i]; j++) {
					int temp = 1;
					for (int cifang = xy[i] - j; cifang > 1; cifang--) // cifang意为 次方
					{
						temp = temp * 10;
					}
					sub_array[i] = sub_array[i] + array[j] * temp;
				}
			} else if (i > 0 && i < n) {
				for (int j = xy[i - 1]; j < xy[i]; j++) {
					int temp = 1;
					for (int cifang = xy[i] - j; cifang > 1; cifang--) {
						temp = temp * 10;
					}
					sub_array[i] = sub_array[i] + array[j] * temp;
				}
			} else {
				for (int j = xy[i - 1]; j < array.length; j++) {
					int temp = 1;
					for (int cifang = array.length - j; cifang > 1; cifang--) {
						temp = temp * 10;
					}
					sub_array[i] = sub_array[i] + array[j] * temp;
				}
			}
		}
		jiSuan_jieguo(n, oi, sub_array, xy); // 计算结果
	}
 
	public static void fuhao_oi_(int[] array, int n, int[] xy, int[] oi, int i) // 第三个递归 用来确定加减号
	{
		if (i == n) {
			jiSuan_even(array, n, xy, oi);
			return;
		}
		for (int k = 0; k <= 1; k++) // 二叉树 0为加 1为减
		{
			oi[i] = k;
			fuhao_oi_(array, n, xy, oi, i + 1);
		}
	}
 
	////////////////////////////////////////////////////////////////////////////////////////////////////////
	public static void fuhaoxy(int[] array, int n, int[] xy, int index)// 第二个递归 确定符号位置
	{
		if (index == n) {
			if (n == 1 && xy[index - 1] > 8) {
				return;
			}
			for (int j = n - 1; j >= 1; j--) // 符号位置不能重合 不要出现重复
			{
				if (xy[j] - xy[j - 1] <= 0) {
					return;
				}
			}
 
			int[] oi = new int[n]; // oi数组 保存符号
			fuhao_oi_(array, n, xy, oi, 0);
 
			return;
		}
 
		for (int i = 1; i <= 8; i++) {
			xy[index] = i;
			fuhaoxy(array, n, xy, index + 1);
		}
	}
 
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	public static void fuhaosum(int[] array, int n)// 第一个递归 确定符号的个数。
	{
		if (n > 8) {
			return;
		}
		int[] xy = new int[n];
		for (int i = 1; i <= n; i++) {
			xy[i - 1] = i;
			fuhaoxy(array, n, xy, 0);
		}
		fuhaosum(array, n + 1);
	}
 
	public static void main(String[] args) {
		int[] array = new int[9];
		for (int i = 1; i <= 9; i++) {
			array[i - 1] = i;
		}
		fuhaosum(array, 1);
	}
}